import math
from scipy import spatial

def Heron_in_node(a, b, c):
    p = (a + b + c) / 2
    S = math.sqrt(p * (p - a) * (p - b) * (p - c))
    h = 2 * S / a
    return h


class Node:  # Node类，记录节点信息，记录坐标、f、g、h以及父节点信息，并定义一些函数
    def __init__(self, point):
        self.point = point
        self.ancient = None
        self.distance = 0
        self.times = 0
        self.cost = 0
        self.similarRate = 0
        self.obloss = 0
        self.totalvalue = math.inf

    def getDis(self, randNode):  # 距离
        self.distance = math.sqrt(pow(randNode.point.x - self.point.x, 2) + pow(randNode.point.y - self.point.y, 2))
        self.distance = self.distance + self.times

    def ancientNode(self, node):  ##获得父亲节点
        self.ancient = node

    def getTotalvalue(self,value):
        self.totalvalue = value

    def getSimilar(self, randNode, endNode):  # 获得相似度
        x_gap = randNode.point.x - self.point.x
        y_gap = randNode.point.y - self.point.y
        vec1 = [x_gap, y_gap]

        x_to_end = endNode.point.x - self.point.x
        y_to_end = endNode.point.y - self.point.y
        vec2 = [x_to_end, y_to_end]
        cos_sim = spatial.distance.cosine(vec1, vec2)  # 取值为0，2，越大越不相似
        self.similarRate = cos_sim

    def getObloss(self, randNode, obstacle):
        x_gap = randNode.point.x - self.point.x
        y_gap = randNode.point.y - self.point.y
        disBetween = math.sqrt(pow(x_gap, 2) + pow(y_gap, 2))
        dangerNum = 0
        for i in obstacle:
            if disBetween == 0:
                break
            newDx = self.point.x - i[0]
            newDy = self.point.y - i[1]
            nearDx = randNode.point.x - i[0]
            nearDy = randNode.point.y - i[1]
            newO = math.sqrt(pow(newDx, 2) + pow(newDy, 2))
            nearO = math.sqrt(pow(nearDx, 2) + pow(nearDy, 2))
            h = Heron_in_node(disBetween, newO, nearO)

            cosnew = (pow(disBetween, 2) + pow(newO, 2) - pow(nearO, 2)) / (2 * newO * disBetween)
            cosnear = (pow(disBetween, 2) + pow(nearO, 2) - pow(newO, 2)) / (2 * nearO * disBetween)  # 余弦定理
            if h <= i[2] and cosnew > 0 and cosnear > 0:
                dangerNum = dangerNum + 1
        self.obloss = dangerNum
